package net.esj.auth.inst.hibernate.dependent.background.manage;

import java.util.Date;
import java.util.HashSet;
import java.util.List;

import net.esj.auth.inst.ssh.manage.AuthManagerImpl;
import net.esj.auth.pojo.CoreAdmin;
import net.esj.auth.pojo.CoreAdmin.ADMIN_STATE;
import net.esj.auth.pojo.CoreAuthFunc;
import net.esj.auth.pojo.CoreAuthModel;
import net.esj.background.manage.LoginManage;
import net.esj.basic.dao.querybuilder.QueryBuilder;
import net.esj.basic.pojo.system.UserRule;
import net.esj.basic.service.provider.UserRuleProvider;
import net.esj.basic.utils.SessionKeyConstants;

import org.apache.commons.lang.StringUtils;
import org.hibernate.FetchMode;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public class LoginManageImpl extends AuthManagerImpl implements
		LoginManage<CoreAdmin>,AuthBgLogin {

	@Override
	@Transactional
	public CoreAdmin doLoginByNameAndPwd(String name, String pwd, String captcha) {
		QueryBuilder<CoreAdmin> qb = createQueryBuilder(CoreAdmin.class);
		
		String pass = pwd;
		if(getPwdEncryptor()!=null){
			pass = getPwdEncryptor().encrypt(pwd, name);
		}
		qb.eq("name", name).eq("password", pass)
		.fetch("groups", FetchMode.SELECT).fetch("functions", FetchMode.SELECT)
		;
		List<CoreAdmin> list = queryListByQueryBuilder(qb);
		
		CoreAdmin admin= null;
		if(!list.isEmpty()){
			admin =  list.get(0);
			if(admin.isSuper()){
				CoreAuthModel model = new CoreAuthModel();
				model.setId(CoreAdmin.MOBJECT_TYPE);
				List<CoreAuthFunc> funcs = findFunctions(null, model, 0,true,false);
				admin.setFunctions(new HashSet<CoreAuthFunc>(funcs));
			}else{
				if(admin.getState() == ADMIN_STATE.FREEZE.getKey()){
					return null;
				}
				admin = getAdminWithAuth(admin.getId());
			}
			admin.getAllowedFunctions();
			admin.setLastLoginTime(new Date());
			admin.setLastLoginIp(getAgentContext().getClient().getIp());
			update(admin);
		}
		if(getAgentContext()!=null && admin!=null){
			getAgentContext().getSession().setAttribute(getSessionKey(), admin);
			getAgentContext().getSession().setMaxInactiveInterval(20*60);//默认设置大后台超市时间20分钟
		}
		return admin;
	}

	@Override
	public Object superLoing(String name, String pwd, String captcha) {
		CoreAdmin admin= new CoreAdmin();
		admin.setName(name);
		CoreAuthModel model = new CoreAuthModel();
		model.setId(CoreAdmin.MOBJECT_TYPE);
		List<CoreAuthFunc> funcs = findFunctions(null, model, 0,true,false);
		admin.setFunctions(new HashSet<CoreAuthFunc>(funcs));
		if(getAgentContext()!=null && admin!=null){
			getAgentContext().getSession().setAttribute(getSessionKey(), admin);
			getAgentContext().getSession().setMaxInactiveInterval(20*60);//默认设置大后台超市时间20分钟
		}
		return admin;
	}
	
	@Override
	public void logout() {
		if(getAgentContext()!=null){
			getAgentContext().getSession().removeAttribute(getSessionKey());
			 getAgentContext().getSession().removeAttribute(getSessionBag());
		}
	}
	
	@Override
	public boolean alterPwd(String oldPwd, String newPwd, String captcha) {
		if(getAgentContext()==null){
			return false;
		}
		Object o = getAgentContext().getSession().getAttribute(getSessionKey());
		if(!(o instanceof CoreAdmin)){
			return false;
		}
		CoreAdmin admin = (CoreAdmin) o;
		String oldAfterEncrypt = oldPwd;
		String newAfterEncryt = newPwd;
		if(getPwdEncryptor()!=null){
			oldAfterEncrypt = getPwdEncryptor().encrypt(oldPwd, admin.getName());
			newAfterEncryt = getPwdEncryptor().encrypt(newPwd, admin.getName());
		}
		if(!StringUtils.equals(oldAfterEncrypt, admin.getPassword())){
			return false;
		}
		admin.setPassword(newAfterEncryt);
		update(admin);
		return true;
	}

	@Override
	public Object getUserInfo() {
		return getAgentContext().getSession().getAttribute(getSessionKey());
	}

	@Override
	public String getUsername() {
		if(getUserInfo()!=null){
			return ((CoreAdmin)getUserInfo()).getName();
		}
		return null;
	}
	
	protected String getSessionKey(){
		UserRule rule = UserRuleProvider.getUserRule(CoreAdmin.class);
		if(rule!=null){
			return rule.getSessionKey();
		}
		return SessionKeyConstants.LOGIN_USER;
	}
	
	protected String getSessionBag(){
		UserRule rule = UserRuleProvider.getUserRule(CoreAdmin.class);
		if(rule!=null){
			return rule.getSessionBag();
		}
		return null;
	}

	@Override
	public boolean isAgency() {
		return false;
	}

}
